﻿using BCCommon;
using BCEntity.TMS.AgentWallet;
using Dapper;
using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;

namespace BCData.TMS.AgentWallet
{
    public class AgentWalletData : IAgentWalletData
    {
        private const string QUERY = @"SELECT
		                                AgentWalletId,
		                                AgentRecordId,
		                                Balance,
		                                PayPassword,
		                                AliPayAuthInfo,
		                                WxPayAuthInfo,
		                                PasswordErrorCount,
		                                FreezeTime
                                    FROM
                                        AgentWallet ";
        private readonly IDatabaseContext database;

        public AgentWalletData(IDatabaseContext database)
        {
            this.database = database;
        }

        public AgentWalletEntity Add(AgentWalletEntity entity)
        {
            return this.database.Master.Insert(entity, database.Transaction);
            //string sql = string.Format(SQL_INSERT_ITEM, QUERY);
            //DynamicParameters parameters = new DynamicParameters();

            //parameters.Add("?AgentRecordId", entity.AgentRecordId, DbType.Int64);
            //parameters.Add("?Balance", entity.Balance, DbType.Decimal);

            //return this.database.Master.QueryFirstOrDefault<AgentWalletEntity>(sql, parameters);
        }

        public AgentWalletEntity Update(AgentWalletEntity entity)
        {
            return this.database.Master.Update(entity, database.Transaction);
            //string sql = string.Format(SQL_UPDATE_ITEM_BY_WALLETID, QUERY);
            //DynamicParameters parameters = new DynamicParameters();

            //parameters.Add("?AgentRecordId", entity.AgentRecordId, DbType.Int64);
            //parameters.Add("?Balance", entity.Balance, DbType.Decimal);
            //parameters.Add("?AgentWalletId", entity.AgentWalletId, DbType.Int64);

            //return this.database.Master.QueryFirstOrDefault<AgentWalletEntity>(sql, parameters);
        }

        public (IEnumerable<AgentWalletEntity>, int) GetPageableList(int pageIndex, int pageSize, long? agentRecordId)
        {
            List<string> wheres = new List<string>();
            DynamicParameters parameters = new DynamicParameters();

            if (agentRecordId.HasValue)
            {
                wheres.Add("AgentRecordId = ?AgentRecordId");
                parameters.Add("?AgentRecordId", agentRecordId.Value, DbType.Int64);
            }
            string sql = string.Format("{0} {1} LIMIT {2}, {3}; SELECT COUNT(1) FROM AgentWallet {1}",
                    QUERY,
                    wheres.Count > 0 ? "WHERE " + string.Join(" AND ", wheres) : string.Empty,
                    (pageIndex - 1) * pageSize,
                    pageSize);

            return this.database.Slave.QueryPageableListAsync<AgentWalletEntity>(sql, parameters).Result;
        }

        public AgentWalletEntity Get(long agentWalletId)
        {
            var sql = typeof(AgentWalletEntity).GetSelectSqlByPrimaryKeys();
            return this.database.Slave.QueryFirstOrDefault<AgentWalletEntity>(sql, new { agentWalletId });

            //string sql = string.Format(SQL_SELECT_ITEM_BY_WALLETID, QUERY);
            //DynamicParameters parameters = new DynamicParameters();

            //parameters.Add("?WalletId", walletId, DbType.Int64);

            //return sqlCommand.QueryFirstOrDefault<AgentWalletEntity>(sql, parameters);
        }

        public AgentWalletEntity GetWalletByAgentRecordId(long agentRecordId)
        {
            var sql = $" {QUERY} WHERE AgentRecordId=?AgentRecordId ";
            return this.database.Slave.QueryFirstOrDefault<AgentWalletEntity>(sql, new { agentRecordId });
            //string sql = string.Format(SQL_SELECT_ITEM_BY_USERID, QUERY);
            //DynamicParameters parameters = new DynamicParameters();

            //parameters.Add("?UserId", userId, DbType.Int64);

            //return sqlCommand.QueryFirstOrDefault<AgentWalletEntity>(sql, parameters);
        }

        public AgentWalletEntity ResetPayPassword(long agentRecordId, string payPwd)
        {
            string sqlUpdate = @"UPDATE AgentWallet
                                SET PayPassword = ?PayPassword
                                WHERE AgentRecordId = ?AgentRecordId;
                                {0} WHERE AgentRecordId = ?AgentRecordId";
            string sql = string.Format(sqlUpdate, QUERY);
            DynamicParameters parameters = new DynamicParameters();
            parameters.Add("?PayPassword", payPwd, DbType.AnsiString);
            parameters.Add("?AgentRecordId", agentRecordId, DbType.Int64);
            return this.database.Master.QueryFirstOrDefault<AgentWalletEntity>(sql, parameters, database.Transaction);
        }

        public int ChangeAliPayAuthInfo(long agentRecordId, string aliPayAuthInfo)
        {
            DynamicParameters parameters = new DynamicParameters();
            string sql = @"UPDATE AgentWallet SET AliPayAuthInfo =?AliPayAuthInfo WHERE AgentRecordId =?AgentRecordId;";
            parameters.Add("?AliPayAuthInfo", aliPayAuthInfo, DbType.AnsiString);
            parameters.Add("?AgentRecordId", agentRecordId, DbType.Int64);
            return this.database.Master.Execute(sql, parameters, database.Transaction);
        }

        public int ChangeWxPayAuthInfo(long agentRecordId, string wxPayAuthInfo)
        {
            DynamicParameters parameters = new DynamicParameters();
            string sql = @"UPDATE AgentWallet SET WxPayAuthInfo =?WxPayAuthInfo WHERE AgentRecordId =?AgentRecordId;";
            parameters.Add("?WxPayAuthInfo", wxPayAuthInfo, DbType.AnsiString);
            parameters.Add("?AgentRecordId", agentRecordId, DbType.Int64);
            return this.database.Master.Execute(sql, parameters, database.Transaction);
        }

        public AgentWalletEntity BalanceRecharge(long agentRecordId, decimal rechargeAmount)
        {
            string sqlUpdate = @"UPDATE AgentWallet
                        SET Balance = ?Balance
                        WHERE AgentRecordId = ?AgentRecordId;
                        {0} WHERE AgentRecordId = ?AgentRecordId";
            string sql = string.Format(sqlUpdate, QUERY);
            DynamicParameters parameters = new DynamicParameters();
            parameters.Add("?Balance", rechargeAmount, DbType.Decimal, size: 10, precision: 2);
            parameters.Add("?AgentRecordId", agentRecordId, DbType.Int64);
            return this.database.Master.QueryFirstOrDefault<AgentWalletEntity>(sql, parameters, database.Transaction);
        }

        public async Task<AgentWalletEntity> UpdatePasswordErrorCount(long agentRecordId, int passwordErrorCount)
        {
            DynamicParameters parameters = new DynamicParameters();
            string sql =
                $@"UPDATE AgentWallet SET PasswordErrorCount =?PasswordErrorCount WHERE AgentRecordId =?UserId; {QUERY} WHERE AgentRecordId =?AgentRecordId";
            if (passwordErrorCount == 3)
            {
                sql = $@"UPDATE AgentWallet SET PasswordErrorCount =?PasswordErrorCount,
                                        FreezeTime=DATE_ADD(now(),INTERVAL 30 MINUTE) WHERE AgentRecordId =?AgentRecordId;
                                        {QUERY} WHERE AgentRecordId =?AgentRecordId";
            }
            parameters.Add("?PasswordErrorCount", passwordErrorCount, DbType.Int32);
            parameters.Add("?AgentRecordId", agentRecordId, DbType.Int64);
            return await this.database.Master.QueryFirstOrDefaultAsync<AgentWalletEntity>(sql, parameters, database.Transaction);
        }

        public async void ClearErrorCount()
        {
            string sql = @"UPDATE AgentWallet SET PasswordErrorCount=0 WHERE FreezeTime<now() AND PasswordErrorCount=3;";
            await this.database.Master.ExecuteAsync(sql, database.Transaction);
        }

        public async Task<bool> UpdateIsOpenOffsetServiceFeeByAgentRecordIdAsync(long agentRecordId)
        {
            string sql = @"UPDATE AgentWallet SET IsOpenOffsetServiceFee=?IsOpenOffsetServiceFee WHERE AgentRecordId=?AgentRecordId;";
            DynamicParameters parameters = new DynamicParameters();
            parameters.Add("?IsOpenOffsetServiceFee", true, DbType.Boolean);
            parameters.Add("?AgentRecordId", agentRecordId, DbType.Int64);
            return await this.database.Master.ExecuteAsync(sql, parameters) > 0;
        }

        public async Task<AgentWalletEntity> UpdateIsOpenOffsetServiceFeeByAgentWalletIdAsync(long agentWalletId, bool isOpenOffsetServiceFee)
        {
            string sqlUpdate = @"UPDATE AgentWallet SET IsOpenOffsetServiceFee=?IsOpenOffsetServiceFee WHERE AgentWalletId=?AgentWalletId;";
            DynamicParameters parameters = new DynamicParameters();
            parameters.Add("?IsOpenOffsetServiceFee", isOpenOffsetServiceFee, DbType.Boolean);
            parameters.Add("?AgentWalletId", agentWalletId, DbType.Int64);
            var sql = $"{sqlUpdate} {QUERY} WHERE WalletId = ?WalletId";
            return await this.database.Master.QueryFirstOrDefaultAsync<AgentWalletEntity>(sql, parameters, database.Transaction);
        }

        public AgentWalletEntity UpdateBalance(long agentWalletId, decimal amount)
        {
            string sql = $@"UPDATE AgentWallet SET Balance=Balance-?Amount WHERE AgentWalletId=?AgentWalletId;
                            {QUERY} WHERE AgentWalletId =?AgentWalletId ";
            return this.database.Master.QueryFirstOrDefault<AgentWalletEntity>(sql, new { agentWalletId, amount }, database.Transaction);
        }
    }
}
